home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 198_01 / display.c < prev    next >
C/C++ Source or Header  |  1990-01-21  |  38KB  |  1,561 lines

  1. /*
  2.  * The functions in this file handle redisplay. There are two halves, the
  3.  * ones that update the virtual display screen, and the ones that make the
  4.  * physical display screen the same as the virtual display screen. These
  5.  * functions use hints that are left in the windows by the commands.
  6.  *
  7.  */
  8.  
  9. #include        <stdio.h>
  10. #include    "estruct.h"
  11. #include        "edef.h"
  12.  
  13. typedef struct  VIDEOTAG {
  14.         int    v_flag;                 /* Flags */
  15. #if    COLOR
  16.     int    v_fcolor;        /* current forground color */
  17.     int    v_bcolor;        /* current background color */
  18.     int    v_rfcolor;        /* requested forground color */
  19.     int    v_rbcolor;        /* requested background color */
  20. #endif
  21.         char    v_text[1];              /* Screen data. */
  22. }       VIDEO;
  23.  
  24. #define VFCHG   0x0001                  /* Changed flag            */
  25. #define    VFEXT    0x0002            /* extended (beyond column 80)    */
  26. #define    VFREV    0x0004            /* reverse video status        */
  27. #define    VFREQ    0x0008            /* reverse video request    */
  28. #define    VFCOL    0x0010            /* color change requested    */
  29. #define    VFSCROL    0x0020            /* cleared by scrolling        */
  30.  
  31. #define    WFSCROL    0x0040            /* window scrolled        */
  32.  
  33. VIDEO   **vscreen;                      /* Virtual screen. */
  34. VIDEO   **vsave;                        /* Used for scrolling. */
  35. #if    MEMMAP == 0
  36. VIDEO   **pscreen;                      /* Physical screen. */
  37. VIDEO   **psave;                        /* Used for scrolling. */
  38. #endif
  39.  
  40. int didlins, didldel;
  41.  
  42. #define fastputc(c)    TTputc(c)
  43.  
  44. /* these declarations must match termio.c */
  45.  
  46. #if     VMS
  47. extern char obuf[NOBUF];                /* Output buffer               */
  48. extern int nobuf;                       /* # of bytes in above    */
  49.  
  50. #undef fastputc
  51. #define fastputc(c)    {if (nobuf >= NOBUF) ttflush(); obuf[nobuf++] = (c);}
  52. #endif
  53.  
  54. #if     V7 | USG | BSD
  55. #undef fastputc
  56. #define fastputc(c)        putc((c), stdout)
  57. #endif
  58.  
  59. #if    (TERMCAP | VMSVT) & COLOR
  60. extern int usedcolor;
  61. #endif
  62.  
  63. /*
  64.  * Initialize the data structures used by the display code. The edge vectors
  65.  * used to access the screens are set up. The operating system's terminal I/O
  66.  * channel is set up. All the other things get initialized at compile time.
  67.  * The original window has "WFCHG" set, so that it will get completely
  68.  * redrawn on the first call to "update".
  69.  */
  70. vtinit()
  71. {
  72.     register int i;
  73.     register VIDEO *vp;
  74.     char *malloc();
  75.  
  76.     TTopen();        /* open the screen */
  77.     TTkopen();        /* open the keyboard */
  78.     TTrev(FALSE);
  79.     if (firstflag) {
  80.     vscreen = (VIDEO **) malloc(term.t_mrow*sizeof(VIDEO *));
  81.     vsave = (VIDEO **) malloc(term.t_mrow*sizeof(VIDEO *));
  82.     }
  83.  
  84.     if (vscreen == NULL || vsave == NULL)
  85.         exit(1);
  86.  
  87. #if    MEMMAP == 0
  88.     if (firstflag) {
  89.     pscreen = (VIDEO **) malloc(term.t_mrow*sizeof(VIDEO *));
  90.     psave = (VIDEO **) malloc(term.t_mrow*sizeof(VIDEO *));
  91.     }
  92.  
  93.     if (pscreen == NULL || psave == NULL)
  94.         exit(1);
  95. #endif
  96.  
  97.     for (i = 0; i < term.t_mrow; ++i)
  98.         {
  99.     if (firstflag) vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_mcol);
  100.     else vp = vscreen[i];
  101.  
  102.         if (vp == NULL)
  103.             exit(1);
  104.  
  105.     vp->v_flag = 0;
  106. #if    COLOR
  107.     vp->v_rfcolor = 7;
  108.     vp->v_rbcolor = 0;
  109. #endif
  110.         vscreen[i] = vp;
  111. #if    MEMMAP == 0
  112.     if (firstflag) vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_mcol);
  113.     else vp = pscreen[i];
  114.  
  115.         if (vp == NULL)
  116.             exit(1);
  117.  
  118.     vp->v_flag = 0;
  119.         pscreen[i] = vp;
  120. #endif
  121.         }
  122. }
  123.  
  124. /*
  125.  * Clean up the virtual terminal system, in anticipation for a return to the
  126.  * operating system. Move down to the last line and clear it out (the next
  127.  * system prompt will be written in the line). Shut down the channel to the
  128.  * terminal.
  129.  */
  130. vttidy()
  131. {
  132. #if    VMSVT | TERMCAP
  133.     ttscroll(0, term.t_nrow, 0);
  134. #endif
  135.     mlerase();
  136.     movecursor(term.t_nrow, 0);
  137.     TTflush();
  138.     TTclose();
  139.     TTkclose();
  140. }
  141.  
  142. /*
  143.  * Set the virtual cursor to the specified row and column on the virtual
  144.  * screen. There is no checking for nonsense values; this might be a good
  145.  * idea during the early stages.
  146.  */
  147. vtmove(row, col)
  148. {
  149.     vtrow = row;
  150.     vtcol = col;
  151. }
  152.  
  153. /* Write a character to the virtual screen. The virtual row and
  154.    column are updated. If we are not yet on left edge, don't print
  155.    it yet. If the line is too long put a "$" in the last column.
  156.    This routine only puts printing characters into the virtual
  157.    terminal buffers. Only column overflow is checked.
  158. */
  159.  
  160. vtputc(c)
  161.  
  162. int c;
  163.  
  164. {
  165.     register VIDEO *vp;    /* ptr to line being updated */
  166.  
  167.     vp = vscreen[vtrow];
  168.  
  169.     if (c == '\t') {
  170.         do {
  171.             vtputc(' ');
  172.         } while (((vtcol + taboff) % tabsize) != 0);
  173.     } else if (vtcol >= term.t_ncol) {
  174.         ++vtcol;
  175.         vp->v_text[term.t_ncol - 1] = '$';
  176.     } else if ((c&0x7F) < 0x20 || (c&0x7F) == 0x7F) {
  177.         vtputc('^');
  178.         vtputc((c&0x7F) ^ 0x40);
  179.     } else {
  180.         if (vtcol >= 0)
  181.             vp->v_text[vtcol] = c;
  182.         ++vtcol;
  183.     }
  184. }
  185.  
  186. /* Write a line to the virtual screen.  Does equivalent of
  187.     for (j=0; j<llength(lp); ++j) vtputc(lgetc(lp, j));
  188.  */
  189.  
  190. vtputl(lp)
  191. register LINE *lp;    /* line to update */
  192. {
  193.     register VIDEO *vp;    /* ptr to line being updated */
  194.     register int i, c;
  195.  
  196.     vp = vscreen[vtrow];
  197.  
  198.     for (i = 0; i < llength(lp); ++i) {
  199.         c = lgetc(lp, i);
  200.         if (c == '\t') {
  201.             do {
  202.                 if (vtcol >= term.t_ncol) {
  203.                     vp->v_text[term.t_ncol - 1] = '$';
  204.                     return;
  205.                 } else {
  206.                     if (vtcol >= 0)
  207.                         vp->v_text[vtcol] = ' ';
  208.                     ++vtcol;
  209.                 }
  210.             } while (((vtcol + taboff) % tabsize) != 0);
  211.         } else if (vtcol >= term.t_ncol) {
  212.             vp->v_text[term.t_ncol - 1] = '$';
  213.             return;
  214.         } else if (c < 0x20 || c >= 0x7F) {
  215.             if ((c&0x7F) < 0x20 || (c&0x7F) == 0x7F) {
  216.                 if (vtcol >= 0) vp->v_text[vtcol] = '^';
  217.                 ++vtcol;
  218.                 if (vtcol >= term.t_ncol) {
  219.                     vp->v_text[term.t_ncol - 1] = '$';
  220.                     return;
  221.                 } else if (vtcol >= 0)
  222.                     vp->v_text[vtcol] = ((c&0x7F) ^ 0x40);
  223.             } else if (vtcol >= 0)
  224.                 vp->v_text[vtcol] = c;
  225.             ++vtcol;
  226.         } else {
  227.             if (vtcol >= 0)
  228.                 vp->v_text[vtcol] = c;
  229.             ++vtcol;
  230.         }
  231.     }
  232. }
  233.  
  234. /* Write a string to the virtual screen and return its length */
  235.  
  236. int vtputs(s)
  237. register char *s;
  238. {
  239.     register VIDEO *vp;    /* ptr to line being updated */
  240.     register int i;
  241.  
  242.     vp = vscreen[vtrow];
  243.  
  244.     for (i = 0; *s != '\0' && vtcol < term.t_ncol; ++i) {
  245.         if (vtcol >= 0) vp->v_text[vtcol] = *(s++);
  246.         ++vtcol;
  247.     }
  248.     return(i);
  249. }
  250.  
  251. /*
  252.  * Erase from the end of the software cursor to the end of the line on which
  253.  * the software cursor is located.
  254.  */
  255. vteeol()
  256. {
  257.     register VIDEO      *vp;
  258.  
  259.     vp = vscreen[vtrow];
  260.     if (vtcol < 0) vtcol = 0;
  261.     while (vtcol < term.t_ncol)
  262.         vp->v_text[vtcol++] = ' ';
  263. }
  264.  
  265. /* upscreen:    user routine to force a screen update
  266.         always finishes complete update        */
  267.  
  268. upscreen(f, n)
  269.  
  270. {
  271.     update(TRUE);
  272.     return(TRUE);
  273. }
  274.  
  275. /*
  276.  * Make sure that the display is right. This is a three part process. First,
  277.  * scan through all of the windows looking for dirty ones. Check the framing,
  278.  * and refresh the screen. Second, make sure that "currow" and "curcol" are
  279.  * correct for the current window. Third, make the virtual and physical
  280.  * screens the same.
  281.  * force == HOOK like FALSE, but also does not update cursor
  282.  *   (for edt page scrolling)
  283.  */
  284. update(force)
  285.  
  286. int force;    /* force update past type ahead? */
  287.  
  288. {
  289.     register WINDOW *wp;
  290.  
  291. #if    TYPEAH
  292.     if (force != TRUE && typahead())
  293.         return(TRUE);
  294. #endif
  295. #if    VISMAC == 0
  296.     if (force != TRUE && kbdmode == PLAY)
  297.         return(TRUE);
  298. #endif
  299.  
  300.     /* update any windows that need refreshing */
  301.     wp = wheadp;
  302.     while (wp != NULL) {
  303.         if (wp->w_flag) {
  304.             /* if the window has changed, service it */
  305.             reframe(wp);    /* check the framing */
  306.             if ((wp->w_flag & ~WFMODE) == WFEDIT)
  307.                 updone(wp);    /* update EDITed line */
  308.             else if ((wp->w_flag & ~(WFMODE | WFMOVE)) == WFSCROL)
  309.                 updscroll(wp);
  310.             else if (wp->w_flag & ~WFMOVE)
  311.                 updall(wp);    /* update all lines */
  312.             if (wp->w_flag & WFMODE)
  313.                 modeline(wp);    /* update modeline */
  314.             wp->w_flag = 0;
  315.             wp->w_force = 0;
  316.         }
  317.         /* on to the next window */
  318.         wp = wp->w_wndp;
  319.     }
  320.  
  321.     /* recalc the current hard